package tonytech.wordcode.service;

import java.io.File;
import java.io.FileFilter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.function.Consumer;

/**
 * class description
 * 特定文件的扫描类
 */
public class DirectoryScanner extends AbstractDirectoryScannerService {
    /**
     * 当扫描path无效时，使用本类。
     */
    private static class UselessDirectoryScanner extends AbstractDirectoryScannerService {
        private UselessDirectoryScanner() {
            super(null);
        }

        @Override
        protected Consumer<File> getFilesScanningMethod(List<File> listToStoreFiles) {
            return getEmptyScanningMethod();
        }

        @Override
        protected Consumer<File> getDirsScanningMethod(List<File> listToStoreDirs) {
            return getEmptyScanningMethod();
        }

        private Consumer<File> getEmptyScanningMethod() {
            return file -> {
            };
        }

        @Override
        public List<File> getFilesInTheRootDirectoryList() {
            return new ArrayList<>(0);
        }

        @Override
        public List<File> getDirectoriesInTheRootDirectoryList() {
            return new ArrayList<>(0);
        }

        @Override
        public List<File> getFilesAndDirsInTheRootDirectoryList() {
            return new ArrayList<>(0);
        }
    }

    private DirectoryScanner(File directory) {
        super(directory);
        filesInTheRootDirectoryList = null;
        directoriesInTheRootDirectoryList = null;
    }

    /**
     * 扫描模板类的工厂方法,输入dir位有效，则返回有效的scanner；否则返回UselessDirectoryScanner
     * @param dir 当前要扫描的文件夹路径
     * @return 新生成的完成扫描的扫描类
     */
     static AbstractDirectoryScannerService newInstance(File dir) {
        AbstractDirectoryScannerService scanner;
        if (dir == null || !dir.exists() || !dir.isDirectory()) {
            scanner = new UselessDirectoryScanner();
        }else{
            scanner  =  new DirectoryScanner(dir);
        }
        scanner.scanDirectory();
        return scanner;

    }


    @Override
    protected Consumer<File> getFilesScanningMethod(List<File> listToStoreFiles) {
        return (File rootDir) ->
                addChildFilesBySpecificFilterIntoSpecificList(
                rootDir,
                File::isFile,
                listToStoreFiles
                );
    }

    @Override
    protected Consumer<File> getDirsScanningMethod(List<File> listToStoreDirs) {
        return rootDir -> addChildFilesBySpecificFilterIntoSpecificList(
                rootDir,
                File::isDirectory,
                listToStoreDirs
        );
    }

    private void addChildFilesBySpecificFilterIntoSpecificList(File dir, FileFilter filter, List<File> list) {
        Collections.addAll(list, dir.listFiles(filter));
    }

    @Override
    public List<File> getFilesAndDirsInTheRootDirectoryList() {
        List<File> result = new ArrayList<>(filesInTheRootDirectoryList);
        result.addAll(directoriesInTheRootDirectoryList);
        return result;
    }

    @Override
    public List<File> getFilesInTheRootDirectoryList() {
        return new ArrayList<>(filesInTheRootDirectoryList);
    }

    @Override
    public List<File> getDirectoriesInTheRootDirectoryList() {
        return new ArrayList<>(directoriesInTheRootDirectoryList);
    }


    @Override
    public String toString() {
        return "DirectoryScanner [filesInTheRootDirectoryList=" + filesInTheRootDirectoryList
                + ", directoriesInTheRootDirectoryList=" + directoriesInTheRootDirectoryList + "]";
    }


}
